---
author: Marcus Rohrmoser
categories:
- en
- sysadmin
date: "2010-08-15T16:12:04+00:00"
tags:
- Graphviz
- MacPorts
- OS X
- Ruby
title: Visualise macports dependencies
type: post
url: /2010/08/visualise-macports-dependencies/
yourls_shorturl:
- http://s.mro.name/1e
---
to clean up your installed macports and remove cruft you need to uninstall them in the correct order – according to their dependencies.

A graphical visualisation might help doing so:

{{< figure  src="/wp-content/uploads/2010/08/port-deps.png" caption="port-deps"  width="188"  height="300" >}}

Call

<pre class="line-numbers"><code class="language-shell-session">
$ ./port-deps2dot.rb | dot -Tpdf -o port-deps.pdf ; open port-deps.pdf
</code></pre>

with the ruby script [`port-deps2dot.rb` (github gist)][2] as follows:

<pre class="line-numbers"><code class="language-ruby">
#!/usr/bin/ruby -w

# visualize macports dependencies.
# pipe the result through graphviz, e.g.
# $ ./port-deps2dot.rb | dot -Tpdf -o port-deps.pdf ; open port-deps.pdf

def scan_deps
  pat = /^([^:]+):(.+)$/
  name = ''
  deps = []
  IO.popen('port info --name --pretty --depends installed') do |f|
    f.each_line do |l|
      case l
        when /^--$/
          yield name, deps
          name = ''
          deps = []
        when /^([^:]+):(.+)$/
          if 'name' == "#$1"
            name = "#$2".strip
          else
            deps.concat("#$2".split(/\s*,\s*/))
          end
        else
          raise "Fall-through for '#{l}'"
      end
    end
  end
end

all = {}

scan_deps do |name,deps|
  d = all[name]
  all[name] = d = [] if d.nil?
  deps.collect! {|i| i.strip}
  d.concat deps
  d.sort!
  d.uniq!
end

head = &lt;&lt;END_OF_STRING
#!/usr/bin/dot -Tpdf -o port-deps.pdf
/*
  See http://www.graphviz.org/Documentation.php
*/
digraph "port deps" {
  rankdir=LR;
    label="port deps";
    node [style=filled,fillcolor=lightblue,shape=ellipse];
    top_level [shape=point];
END_OF_STRING

puts head

all.keys.sort.each do |name|
  deps = all[name]
  if deps.count > 0
    deps.each {|d| puts "\t\"#{name}\" -> \"#{d}\";" }
  else
    puts "\t\"#{name}\";"
  end
end

foot = &lt;&lt;END_OF_STRING
}
END_OF_STRING

puts foot
</code></pre>

 [1]: http://blog.mro.name/wp-content/uploads/2010/08/port-deps.png
 [2]: https://gist.github.com/794713
